//
//  GameObjectLayer.m
//  Agility
//
//  Created by Dominique d'Argent on 15.03.11.
//  Copyright 2011 Nicky Nubbel. All rights reserved.
//

#import "GameObjectLayer.h"


@implementation GameObjectLayer

@synthesize size;

#pragma mark Object lifecycle

//
// initWithGameObjectKey:
//
// Creates a new layer and establishes the link to the game object identified
// by a given key.
//
- (id)initWithGameObjectKey:(NSString *)newGameObjectKey {
    self = [self init];
    
    if (self) {
        gameObjectKey = [newGameObjectKey copy];
    
        GameObject *gameObject = [[GameData sharedGameData] gameObjectForKey:gameObjectKey];
        
        // assign to the game object; FIXME: remove this link
        gameObject.layer = self;
        
        [[GameData sharedGameData].gameObjects addObserver:self
                                                forKeyPath:gameObjectKey
                                                   options:NSKeyValueObservingOptionNew
                                                   context:nil];
        
        
        // init
        [self update];
        
//        self.borderWidth = 5.0f;
//        self.borderColor = [UIColor redColor].CGColor;
        
        // save size before transformations;
        size = self.frame.size;
    }
    
    return self;
}

//
// dealloc
//
// Releases retained objects and stops observing the linked game object.
- (void)dealloc {
    if (gameObjectKey) {
        [[GameData sharedGameData].gameObjects removeObserver:self forKeyPath:gameObjectKey];
    }
    
    [gameObjectKey release];
    
    [super dealloc];
}

//
// update
//
// Updates the layer with the new values of the linked game object.
//
- (void)update {
    GameObject *gameObject = [[GameData sharedGameData] gameObjectForKey:gameObjectKey];
    
    self.imageName  = gameObject.imageName;
    self.hidden     = !gameObject.visible;
    
    // animated movement
    [CATransaction begin];
    [CATransaction setAnimationDuration:gameObject.durationForMovement];
    [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
    self.position = gameObject.position;
    [CATransaction commit];
    
    // animated rotation
    [CATransaction begin];
    [CATransaction setAnimationDuration:gameObject.durationForRotation];
    [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
    self.transform  = CATransform3DMakeRotation(-gameObject.angle, 0, 0, 1.0f);  
    [CATransaction commit];
}

# pragma mark - KVO

//
// observeValueForKeyPath:ofObject:change:context:
//
// Dispatches KVO events.
//
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqualToString:gameObjectKey]) {
        GameObject *gameObject = [change objectForKey:NSKeyValueChangeNewKey];
        
        // check if the game object was removed from the game data dictionary
        if ([gameObject isEqual:[NSNull null]]) {
            [self removeFromSuperlayer];
        }
        
        // update layer
        [self update];
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

@end
